#region Licence
// Copyright (c) 2008 Tasman Logic Ltd

// Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
// and associated documentation files (the "Software"), to deal in the Software without restriction, 
// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all copies 
// or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Reflection;
using System.Reflection.Emit;
using ActiveSharp.Utils;

namespace ActiveSharp.Inspection
{
    /// <summary>
    /// Lists of opcodes, indexed by OpCode.Value, and grouped into lists for 1 byte and 2 byte opcodes.
    /// </summary>
    /// <remarks>As of .NET 2.0, 4 byte opcodes are listed as a future possibility in the ECMA standard, but are not yet 
    /// present in the .NET Framework, so we don't accommodate them there.</remarks>
    static class OpCodeLists
    {
        public static readonly OpCode?[] SingleByte = new OpCode?[0x100];
        public static readonly OpCode?[] DoubleByte = new OpCode?[0x100];

        /// <summary>
        /// Create the lists, by reflecting over <see cref="OpCodes"/>, and indexing all members, by <see cref="OpCode.Value"/>
        /// </summary>
        static OpCodeLists()
        {
            foreach (FieldInfo fi in typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static))
            {
                OpCode opCode = (OpCode)fi.GetValue(null);
                UInt16 value = (UInt16)opCode.Value;
                if (value < 0x100)
                    SingleByte[value] = opCode;
                else if ((value & 0xff00) == 0xfe00)        //all 2 byte codes begin with FE
                    DoubleByte[value & 0xff] = opCode;      //index by lower byte only
                else
                    throw new UnexpectedCaseException();
            }
        }
    }
}


